package connect4.swing2;

/**
 * File: ConnectFour.java
 * Author: Brian Borowski
 * Date created: April 9, 2012
 * Date last modified: September 1, 2012
 */
import gnu.getopt.Getopt;

import java.util.Scanner;

import connect4.Connect4Model;
import connect4.Piece;
import connect4.Result;

public class ConnectFour {
    private Piece player;
    private final int gameType, maxDepth;
    private int plays;
    private static Scanner input = new Scanner(System.in);
    
    private final Connect4Model model;

    public ConnectFour(int gameType, int maxDepth)
            throws IllegalArgumentException {
        this.gameType = gameType;
        this.maxDepth = maxDepth;
        player = Piece.WHITE;
        plays = 0;
        model = new Connect4Model();
    }

    public int getGameType() {
        return gameType;
    }

    public int getMaxDepth() {
        return maxDepth;
    }

    public int getPlays() {
        return plays;
    }

    public int getMaxPlays() {
        return Connect4Model.HEIGHT * Connect4Model.WIDTH;
    }

    public Piece getPlayer() {
        return player;
    }

//    public Board getBoard() {
//        return board;
//    }
    
    public Connect4Model getModel() {
    	return model;
    }

//    public void displayBoard() {
//        board.display();
//    }

    public void switchPlayers() {
        if (player == Piece.BLACK) {
            player = Piece.WHITE;
        } else {
            player = Piece.BLACK;
        }
    }

    public Result getResult() {
        return model.checkResult();
    }

    public void dropChecker(int col, Piece player)
            throws IllegalArgumentException {
        if (player != Piece.WHITE && player != Piece.BLACK) {
            throw new IllegalArgumentException(
                "Invalid player '" + player + "' attempting to mark board.");
        }
        if (col < 0 || col >= Connect4Model.WIDTH) {
            throw new IllegalArgumentException(
                "Invalid column " + col + " received.");
        }
        model.mark(col, player);
        plays++;
    }

    public static int getColumn(Piece player, int maxCol)
            throws IllegalArgumentException {

//        String color = Board.getColorOfPlayer(player);

        System.out.print(
                "Drop a " + player + " checker at column (1.." + maxCol
                + "): ");
        int column = 0;
        String strColumn = input.nextLine().trim();
        try {
            column = Integer.parseInt(strColumn);
        } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException(
                "Invalid column '" + strColumn + "' received.");
        }
        if (column < 1 || column > maxCol) {
            throw new IllegalArgumentException(
                "Invalid column " + column + " received.");
        }
        return column - 1;
    }

    public static String getHelp(String programName) {
        StringBuilder builder = new StringBuilder("Usage: java " + programName
                + " [options]\n");
        builder.append("   -g game type [1-4], where\n");
        builder.append("      1 = HUMAN vs. HUMAN\n");
        builder.append("      2 = HUMAN vs. COMPUTER [default]\n");
        builder.append("      3 = COMPUTER vs. HUMAN\n");
        builder.append("      4 = COMPUTER vs. COMPUTER\n");
        builder.append("   -m difficulty level [1-4], where\n");
        builder.append("      1 = BEGINNER\n");
        builder.append("      2 = INTERMEDIATE\n");
        builder.append("      3 = ADVANCED\n");
        builder.append("      4 = EXPERT [default]");
        return builder.toString();
    }

    private static ConnectFourConfig parseArgs(String programName, String[] args) {
        Getopt g = new Getopt(programName, args, "g:hm:");
        g.setOpterr(false);
        int c,
            gameType = ConnectFourConfig.HUMAN_ADRIANAI,
            difficultyLevel = ConnectFourConfig.EXPERT;
        String arg;
        while ((c = g.getopt()) != -1) {
            switch (c) {
                case 'g':
                    arg = g.getOptarg();
                    try {
                        gameType = Integer.parseInt(arg);
                        if (gameType < ConnectFourConfig.HUMAN_HUMAN ||
                            gameType > ConnectFourConfig.COMPUTER_COMPUTER) {
                            throw new NumberFormatException();
                        }
                    } catch (NumberFormatException nfe) {
                        System.err.println(programName
                                + ": Invalid game type '" + arg
                                + "'.");
                        System.exit(1);
                    }
                    break;
                case 'h':
                    System.out.println(getHelp(programName));
                    System.exit(0);
                case 'd':
                    arg = g.getOptarg();
                    try {
                        difficultyLevel = Integer.parseInt(arg);
                        if (difficultyLevel < ConnectFourConfig.BEGINNER ||
                            difficultyLevel > ConnectFourConfig.EXPERT) {
                            throw new NumberFormatException();
                        }
                    } catch (NumberFormatException nfe) {
                        System.err.println(programName +
                                ": Invalid max depth '" + arg + "'.");
                        System.exit(1);
                    }
                    break;
                case '?':
                    System.err.println(programName + ": Unknown option '"
                            + (char)g.getOptopt() + "' received.");
                    System.exit(1);
                default:
                    break;
            }
        }
        return new ConnectFourConfig(gameType, difficultyLevel);
    }
}